/*!
	@file
	@author		George Evmenov
	@date		07/2009
*/

#include "MyGUI_EggRenderManager.h"
#include "MyGUI_EggTexture.h"
#include "MyGUI_EggVertexBuffer.h"
#include "MyGUI_EggDiagnostic.h"
#include "MyGUI_VertexData.h"
#include "MyGUI_Gui.h"
#include "MyGUI_Timer.h"

namespace MyGUI{

	EggRenderManager& EggRenderManager::getInstance()
	{
		return *getInstancePtr();
	}

	EggRenderManager* EggRenderManager::getInstancePtr()
	{
		return static_cast<EggRenderManager*>(RenderManager::getInstancePtr());
	}

	EggRenderManager::EggRenderManager() :
		mUpdate(false),
		mIsInitialise(false)
	{
	}

	void EggRenderManager::initialise()
	{
		MYGUI_PLATFORM_ASSERT(!mIsInitialise, getClassTypeName() << " initialised twice");
		MYGUI_PLATFORM_LOG(Info, "* Initialise: " << getClassTypeName());
		mVertexFormat = VertexColourType::ColourABGR;
		mUpdate = false;

        using namespace egg;
        Renderer::getSingletonPtr();
        mGUIShader=ShaderPtr(new Shader());
        mGUIShader->fromFile("glsl/gui.vs","glsl/gui.fs");
        mGUIParamMap.bindShader(mGUIShader);
        mGUITexture=mGUIParamMap.getTextureParam("uni_sampler2D_color");


		MYGUI_PLATFORM_LOG(Info, getClassTypeName() << " successfully initialized");
		mIsInitialise = true;
	}

	void EggRenderManager::shutdown()
	{
		MYGUI_PLATFORM_ASSERT(mIsInitialise, getClassTypeName() << " is not initialised");
		MYGUI_PLATFORM_LOG(Info, "* Shutdown: " << getClassTypeName());

		destroyAllResources();

		MYGUI_PLATFORM_LOG(Info, getClassTypeName() << " successfully shutdown");
		mIsInitialise = false;
	}

	IVertexBuffer* EggRenderManager::createVertexBuffer()
	{
		return new EggVertexBuffer();
	}

	void EggRenderManager::destroyVertexBuffer(IVertexBuffer* _buffer)
	{
		delete _buffer;
	}

	void EggRenderManager::doRender(IVertexBuffer* _buffer, ITexture* _texture, size_t _count){
		EggVertexBuffer* buffer = static_cast<EggVertexBuffer*>(_buffer);
        EggTexture* texture = static_cast<EggTexture*>(_texture);
        mGUITexture->mTexture=texture->_mTexture;
        mGUIParamMap._commitParamsForce();
        egg::StateCache::disableDepthTest();
        buffer->draw(_count);
	}

	void EggRenderManager::begin(){
        using namespace egg;
        StateCache::enableCull(GL_CW,GL_BACK);
        StateCache::enableBlend(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	}

	void EggRenderManager::end(){
	}

	const RenderTargetInfo& EggRenderManager::getInfo(){
		return mInfo;
	}

	const IntSize& EggRenderManager::getViewSize() const{
		return mViewSize;
	}

	VertexColourType EggRenderManager::getVertexFormat()
	{
		return mVertexFormat;
	}

	bool EggRenderManager::isFormatSupported(PixelFormat _format, TextureUsage _usage)
	{
		return true;
	}

	void EggRenderManager::drawOneFrame(){
		Gui* gui = Gui::getInstancePtr();
		if (gui == nullptr)
			return;

		static Timer timer;
		static unsigned long last_time = timer.getMilliseconds();
		unsigned long now_time = timer.getMilliseconds();
		unsigned long time = now_time - last_time;

		onFrameEvent((float)((double)(time) / (double)1000));

		last_time = now_time;

		begin();
		onRenderToTarget(this, mUpdate);
		end();

		mUpdate = false;
	}

	void EggRenderManager::setViewSize(int _width, int _height)
	{
		if (_height == 0)
			_height = 1;
		if (_width == 0)
			_width = 1;

		mViewSize.set(_width, _height);

		mInfo.maximumDepth = 1;
		mInfo.hOffset = 0;
		mInfo.vOffset = 0;
		mInfo.aspectCoef = float(mViewSize.height) / float(mViewSize.width);
		mInfo.pixScaleX = 1.0f / float(mViewSize.width);
		mInfo.pixScaleY = 1.0f / float(mViewSize.height);

		onResizeView(mViewSize);
		mUpdate = true;
	}

	ITexture* EggRenderManager::createTexture(const std::string& _name){
		MapTexture::const_iterator item = mTextures.find(_name);
		MYGUI_PLATFORM_ASSERT(item == mTextures.end(), "Texture '" << _name << "' already exist");

		EggTexture* texture = new EggTexture(_name);
		mTextures[_name] = texture;
		return texture;
	}

	void EggRenderManager::destroyTexture(ITexture* _texture)
	{
		if (_texture == nullptr)
			return;

		MapTexture::iterator item = mTextures.find(_texture->getName());
		MYGUI_PLATFORM_ASSERT(item != mTextures.end(), "Texture '" << _texture->getName() << "' not found");

		mTextures.erase(item);
		delete _texture;
	}

	ITexture* EggRenderManager::getTexture(const std::string& _name)
	{
		MapTexture::const_iterator item = mTextures.find(_name);
		if (item == mTextures.end())
			return nullptr;
		return item->second;
	}

	void EggRenderManager::destroyAllResources()
	{
		for (MapTexture::const_iterator item = mTextures.begin(); item != mTextures.end(); ++item)
		{
			delete item->second;
		}
		mTextures.clear();
	}

} // namespace MyGUI
